package com.example.springboottestgit.service;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.CountResponse;
import co.elastic.clients.elasticsearch.core.DeleteByQueryResponse;
import co.elastic.clients.elasticsearch.core.IndexResponse;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.elasticsearch.indices.DeleteIndexResponse;
import co.elastic.clients.json.JsonData;
import co.elastic.clients.transport.endpoints.BooleanResponse;
import com.example.springboottestgit.bean.BusinessException;
import com.example.springboottestgit.bean.dto.EconomicPolicyDTO;
import com.example.springboottestgit.bean.vo.EconomicPolicyContent;
import com.example.springboottestgit.enums.ExceptionCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @description:
 * @author: ZZZ
 */
@Slf4j
@Service
public class ElasticSearchClientServer {

    @Value("${index.name}")
    private String indexName;


    @Value("${file.read.path}")
    private String fileReadPath;


    @Autowired
    private ElasticsearchClient client;

    //创建索引
    public void createIndex(String indexName) throws IOException {
        client.indices().create(c -> c.index(indexName));
    }

    public boolean existsTest(String indexName) throws IOException {
        BooleanResponse booleanResponse = client.indices().exists(e -> e.index(indexName));
        return booleanResponse.value();
    }

    public boolean deleteTest(String indexName) throws IOException {
        DeleteIndexResponse deleteIndexResponse = client.indices().delete(d -> d.index(indexName));
        return deleteIndexResponse.acknowledged();
    }

    public void del_content_10000() {


        try {
            String INDEX_NAME = "ep20251118";
            int CONTENT_LENGTH_THRESHOLD = 10000;
            // 检查索引是否存在
            BooleanResponse exists = client.indices().exists(e -> e.index(indexName));
            if (!exists.value()) {
                System.err.println("❌ 索引 [" + indexName + "] 不存在！");
                return;
            }

            // 获取文档总数
            CountResponse countResponse = client.count(c -> c.index(indexName));
            long totalCount = countResponse.count();
            System.out.println("删除前文档个数：" + totalCount);


            // 使用Painless脚本删除长内容文档
            String painlessScript =
                    "if (ctx._source.content != null) { " +
                            "  return ctx._source.content.length() > " + CONTENT_LENGTH_THRESHOLD + "; " +
                            "} else { " +
                            "  return false; " +
                            "}";

            DeleteByQueryResponse response = client.deleteByQuery(d -> d
                    .index(INDEX_NAME)
                    .query(q -> q
                            .script(sq -> sq
                                    .script(ss -> ss
                                            .inline(is -> is
                                                    .lang("painless")
                                                    .source(painlessScript)
                                            )
                                    )
                            )
                    )
                    .refresh(true)
            );

            System.out.println("删除完成:");
            System.out.println("删除文档数: " + response.deleted());
            System.out.println("耗时: " + response.took() + "ms");


            CountResponse countResponse2 = client.count(c -> c.index(indexName));
            long totalCount2 = countResponse2.count();
            System.out.println("删除前文档个数：" + totalCount2);


        } catch (IOException e) {
            System.err.println("❌ 删除操作失败：");
            e.printStackTrace();
        }
    }

    public void reloadText() {
        try {
            LocalDateTime startTime = LocalDateTime.now();
            BooleanResponse exists = client.indices().exists(e -> e.index(indexName));
            if (exists.value()) {
                client.indices().delete(d -> d.index(indexName));
                Thread.sleep(5000);
            }
            File rootDirectory = new File(fileReadPath);
            // 存储找到的 .txt 文件的列表
            List<File> txtFiles = new ArrayList<>();
            // 调用递归方法来查找 .txt 文件
            findTxtFiles(rootDirectory, txtFiles);
            int n = 0;
            int m = 0;
            int z = 0;

            // 打印找到的 .txt 文件
            for (File txtFile : txtFiles) {
                //EconomicPolicyContent economicPolicyContent = fileNameAndContent(txtFile.getAbsolutePath());
                EconomicPolicyContent economicPolicyContent = fileNameAndContent(txtFile.getPath());
                String content = economicPolicyContent.getContent();
                if (content.length() < 500) {
                    n++;
                    continue;

                }

                if (content.length() > 10000) {
                    m++;
                    continue;
                }
                z++;
                System.out.println(z);


                
                log.info("年份：{} 文件名:{} 内容长度：{}", economicPolicyContent.getYear(), economicPolicyContent.getName(), economicPolicyContent.getContent().length());
                IndexResponse indexResponse = client.index(i -> i.index(indexName)
                        //设置id
                        //.id("1")
                        //传入user对象
                        .document(economicPolicyContent));
                Thread.sleep(10);

            }
            System.out.println("福州经济政策文件");
            System.out.println(String.format("文件总个数 %d 个", z));
            System.out.println(String.format("字数少于500的文件 %d 个", n));
            System.out.println(String.format("字数大于1W 的文件 %d 个", m));

            LocalDateTime endTime = LocalDateTime.now();
            Duration between2 = Duration.between(startTime, endTime);
            log.info("索引:{} 新增{}记录 耗时{}妙", indexName, txtFiles.size(), between2.getSeconds());

        } catch (Exception e) {
            log.error("=====es reload 失败=====", e);
            throw new BusinessException(ExceptionCodeEnum.BUSINESS_ERROR.getCode(), ExceptionCodeEnum.BUSINESS_ERROR.getMessage());

        }
    }

    private void findTxtFiles(File directory, List<File> txtFiles) {
        // 检查目录是否存在且是一个目录
        if (directory.exists() && directory.isDirectory()) {
            // 获取目录中的所有文件和子目录
            File[] files = directory.listFiles();
            if (files != null) {
                for (File file : files) {
                    // 如果是目录，递归调用
                    if (file.isDirectory()) {
                        findTxtFiles(file, txtFiles);
                    } else {
                        // 如果是文件且扩展名为 .txt，添加到列表中
                        if (file.isFile() && file.getName().endsWith(".txt")) {
                            txtFiles.add(file);
                        }
                    }
                }
            }
        }
    }


    //查询
    public List<String> queryContent(String indexName, EconomicPolicyDTO dto, int size) throws IOException {
        String result = "";

        SearchResponse<EconomicPolicyContent> search;

        if (dto.getStartYear() != null && dto.getEndYear() != null) {
            search = client.search(x -> x
                            .index(indexName)
                            .query(q -> q.bool(b -> b
                                    .must(m -> m
                                            .match(match -> match
                                                    .field("content").query(dto.getQuestion())))
                                    .filter(f -> f
                                            .range(r -> r
                                                    .field("year").gte(JsonData.of(dto.getStartYear())).lte(JsonData.of(dto.getEndYear()))))))
                            .from(0).size(size)

                    , EconomicPolicyContent.class);

        } else {
            search = client.search(x -> x
                            .index(indexName)
                            .query(q -> q.bool(b -> b.must(m -> m.match(match -> match.field("content").query(dto.getQuestion())))))
                            .from(0).size(size)

                    , EconomicPolicyContent.class);

        }
        List<String> list = new ArrayList<>();


        for (Hit<EconomicPolicyContent> hit : search.hits().hits()) {
            //esult = result + hit.source().getContent() + "\n\n*****\n\n";
//            System.out.println(hit.source().getYear());
//            System.out.println(hit.source().getFileContent());
//            System.out.println("\n");
            list.add(hit.source().getContent());

        }
        //System.out.println(result);
        return list;
    }


    public EconomicPolicyContent fileNameAndContent(String filePath) throws IOException {
        EconomicPolicyContent economicPolicyContent = new EconomicPolicyContent();
        File file = new File(filePath);
        String fileName = file.getName();
        FileReader reader = new FileReader(filePath);
        BufferedReader bufferedReader = new BufferedReader(reader);
        StringBuilder stringBuilder = new StringBuilder();
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            stringBuilder.append(line).append("\n");
            ;
        }
        bufferedReader.close();
        //log.info(filePath);
        //从文件路径查找年份，window 文件路径：\\  linux:/
        int e = filePath.lastIndexOf("\\");
        String year = filePath.substring(e - 4, e);
        boolean b = year.matches("\\d{4}");

        if (b) {
            economicPolicyContent.setYear(Integer.valueOf(year));
        } else {
            System.out.println(filePath);
        }
        economicPolicyContent.setName(fileName);
        economicPolicyContent.setContent(stringBuilder.toString());
        return economicPolicyContent;
    }

}
